package com.sayice.robotconflict.view.sprite

import androidx.compose.animation.core.animateIntOffsetAsState
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntOffset
import com.sayice.robotconflict.Game
import com.sayice.robotconflict.model.property.Coord
import com.sayice.robotconflict.model.receive.GameRobotInfo
import com.sayice.robotconflict.model.receive.GameTowerInfo
import com.sayice.robotconflict.ui.screen.cdp
import com.sayice.robotconflict.ui.screen.cpx
import com.sayice.robotconflict.viewmodel.GameViewModel
import kotlin.math.roundToInt

/**
 * 机器人
 *
 * @param robot 对局机器人信息
 * @param bloodColor 血量条颜色
 * @param marked 是否标记
 * @param attacking 是否正在攻击
 * @param onClick 点击回调
 * @param viewModel ViewModel
 */
@Composable
fun RobotSprite(
    robot: GameRobotInfo,
    bloodColor: Color,
    marked: Boolean = false,
    attacking: Boolean = false,
    onClick: (() -> Unit)? = null,
    viewModel: GameViewModel
) {
    var attackOffset by remember { mutableStateOf(IntOffset.Zero) }
    if (robot.attackOffset.x != 0.0) {
        attackOffset = IntOffset(
            viewModel.directionOf(robot.attackOffset.x.cpx.roundToInt()),
            viewModel.directionOf(robot.attackOffset.y.cpx.roundToInt())
        )
    }
    val energyBallOffset by animateIntOffsetAsState(
        targetValue = attackOffset,
        finishedListener = { attackOffset = IntOffset.Zero }
    )
    var modifier = Modifier
        .offset(
            (viewModel.xOf(robot.coord.x) - (Game.ROBOT_ATTACK_RADIUS - Game.ROBOT_SIZE / 2)).cdp,
            (viewModel.yOf(robot.coord.y) - (Game.ROBOT_ATTACK_RADIUS - Game.ROBOT_SIZE / 2)).cdp
        )
        .size((2 * Game.ROBOT_ATTACK_RADIUS).cdp)
    if (attacking && robot.playerId == viewModel.loginInfo.playerId && robot.controlled) {
        modifier = modifier.border(2.cdp, Color.Blue, CircleShape)
    }
    Box(modifier = modifier) {
        Box(modifier = Modifier
            .align(Alignment.Center)
            .size((Game.ROBOT_SIZE + 80).cdp).let {
                if (marked) it.border(1.cdp, Color.DarkGray, CircleShape) else it
            }) {
            Image(
                painter = ColorPainter(Color.Blue), contentDescription = null,
                alpha = if (attackOffset != IntOffset.Zero) 1.0f else 0.0f,
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset { energyBallOffset }
                    .clip(CircleShape)
                    .size(20.cdp)
            )
            Column(
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset(y = (-25).cdp)
                    .size(Game.ROBOT_SIZE.cdp, (Game.ROBOT_SIZE + 50).cdp)
            ) {
                Text(
                    text = robot.blood.toString(),
                    modifier = Modifier.size(Game.ROBOT_SIZE.cdp, 50.cdp),
                    color = bloodColor,
                    textAlign = TextAlign.Center
                )
                Image(
                    painter = ColorPainter(Color.Blue), contentDescription = null,
                    modifier = Modifier.size(Game.ROBOT_SIZE.cdp).let {
                        if (onClick == null) it else it.clickable(onClick = onClick)
                    }
                )
            }
        }
    }
}

/**
 * 能量塔
 *
 * @param coord 坐标
 * @param tower 对局能量塔信息
 * @param isRival 是否是敌方的
 * @param viewModel ViewModel
 */
@Composable
fun TowerSpirit(
    coord: Coord,
    tower: GameTowerInfo,
    isRival: Boolean = false,
    viewModel: GameViewModel
) {
    Box(
        modifier = Modifier
            .offset(
                (viewModel.xOf(coord.x) - (Game.TOWER_ENERGY_RADIUS - Game.TOWER_SIZE / 2)).cdp,
                (viewModel.yOf(coord.y) - (Game.TOWER_ENERGY_RADIUS - Game.TOWER_SIZE / 2)).cdp
            )
            .size((2 * Game.TOWER_ENERGY_RADIUS).cdp)
            .border(2.cdp, Color.Blue, CircleShape)
    ) {
        Column(
            modifier = Modifier
                .align(Alignment.Center)
                .offset(y = (if (isRival) 25 else -25).cdp)
                .size(Game.TOWER_SIZE.cdp, (Game.TOWER_SIZE + 50).cdp)
        ) {
            if (isRival) {
                Image(
                    painter = ColorPainter(Color.Blue), contentDescription = null,
                    modifier = Modifier
                        .size(Game.TOWER_SIZE.cdp)
                        .drawBehind {
                            drawLine(
                                color = Color.Red, start = Offset(50.cpx, 50.cpx),
                                end = Offset(
                                    (50 + tower.attackOffset.x).cpx,
                                    (50 + tower.attackOffset.y).cpx
                                ),
                                strokeWidth = 1.0f
                            )
                        }
                )
                Text(
                    text = tower.blood.toString(),
                    modifier = Modifier.size(Game.TOWER_SIZE.cdp, 50.cdp),
                    color = Color.Red,
                    textAlign = TextAlign.Center
                )
            } else {
                Text(
                    text = tower.blood.toString(),
                    modifier = Modifier.size(Game.TOWER_SIZE.cdp, 50.cdp),
                    color = Color.Blue,
                    textAlign = TextAlign.Center
                )
                Image(
                    painter = ColorPainter(Color.Blue), contentDescription = null,
                    modifier = Modifier
                        .size(Game.TOWER_SIZE.cdp)
                        .drawBehind {
                            drawLine(
                                color = Color.Blue, start = Offset(50.cpx, 50.cpx),
                                end = Offset(
                                    (50 + tower.attackOffset.x).cpx,
                                    (50 + tower.attackOffset.y).cpx
                                ),
                                strokeWidth = 1.0f
                            )
                        }
                )
            }
        }
    }
}
